const mockData = [
  {
    "resourceId": "1951707978876321793",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/20250803021337f40c027e51a840ab.jpg",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20250803021348e896391ace154817.jpg",
    "type": 1,
    "title": "横幅：清积水 灭蚊子 防叮咬-6x0.8m",
    "description": "",
    "createTime": "2025-08-03 02:13:38",
    "maxShowHeight": 2268,
    "maxShowWidth": 17008,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1951689278110564354",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/20250803005919f12a983270c0497a.png",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20250803005951bc5f7b4b324c4004.jpg",
    "type": 1,
    "title": "横幅：灭蚊无旁观者  你我皆是防线-10x0.8m",
    "description": "",
    "createTime": "2025-08-03 00:59:19",
    "maxShowHeight": 156,
    "maxShowWidth": 1910,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1951689278056038401",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/202508030059196c0aa95aa9754400.png",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20250803005951285563043d9e4608.jpg",
    "type": 1,
    "title": "横幅：全民齐动手 蚊虫无处藏-8x0.8m",
    "description": "",
    "createTime": "2025-08-03 00:59:19",
    "maxShowHeight": 192,
    "maxShowWidth": 1919,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1951689277972152322",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/2025080300591910a80db2cbbc4dc1.png",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20250803005951103aea2ee1c84433.jpg",
    "type": 1,
    "title": "横幅：预防“两热”  防蚊灭蚊是关键-10x0.8m",
    "description": "",
    "createTime": "2025-08-03 00:59:19",
    "maxShowHeight": 153,
    "maxShowWidth": 1918,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1951689277829545985",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/20250803005919f39ede466ee64133.png",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/202508030059510bc019f54ed64952.jpg",
    "type": 1,
    "title": "横幅：清积水 灭蚊子 防叮咬-8x0.8m",
    "description": "",
    "createTime": "2025-08-03 00:59:19",
    "maxShowHeight": 192,
    "maxShowWidth": 1917,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1951676629150859265",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/20250803000903eaef00e6b652464f.jpg",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20250803001053d5f661fd936040a2.jpg",
    "type": 1,
    "title": "横幅：预防“两热”  防蚊灭蚊是关键-7x0.8m",
    "description": "",
    "createTime": "2025-08-03 00:09:03",
    "maxShowHeight": 2268,
    "maxShowWidth": 19843,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1951676629167636481",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/202508030009037b27c78bd22044d8.jpg",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20250803001047a878aed9f9e644f1.jpg",
    "type": 1,
    "title": "横幅：预防“两热”  防蚊灭蚊是关键-9x0.8m",
    "description": "",
    "createTime": "2025-08-03 00:09:03",
    "maxShowHeight": 2268,
    "maxShowWidth": 25512,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1951676567582670849",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/20250803000848fa990776fa1a43ad.jpg",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20250803001054ec98b2e216224f75.jpg",
    "type": 1,
    "title": "横幅：灭蚊无旁观者  你我皆是防线-8x0.8m",
    "description": "",
    "createTime": "2025-08-03 00:08:49",
    "maxShowHeight": 2268,
    "maxShowWidth": 19843,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1951667712949747713",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/20250802233337a37544242ddc49e2.png",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20250802233415665d87af1a2b4ec2.jpg",
    "type": 1,
    "title": "防蚊灭蚊”七天七招“",
    "description": "",
    "createTime": "2025-08-02 23:33:38",
    "maxShowHeight": 3840,
    "maxShowWidth": 2880,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1951667711943114754",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/20250802233337862738b3507c4c26.png",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20250802233415bef4897528734f9c.jpg",
    "type": 1,
    "title": "防蚊灭蚊“1130”行动",
    "description": "",
    "createTime": "2025-08-02 23:33:37",
    "maxShowHeight": 3840,
    "maxShowWidth": 2880,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1951115146574692353",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/2025080110575510773867a8394cf4.png",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20250801105812446b89955f5e4cee.jpg",
    "type": 1,
    "title": "",
    "description": "",
    "createTime": "2025-08-01 10:57:56",
    "maxShowHeight": 2160,
    "maxShowWidth": 3240,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1951115141080154114",
    "relativeId": "1942769164837453825",
    "relativeType": "4",
    "content": "image/20250801105754a9c4d61c1b774f1a.png",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/202508011058122596dff7c50e49f2.jpg",
    "type": 1,
    "title": "",
    "description": "",
    "createTime": "2025-08-01 10:57:54",
    "maxShowHeight": 2160,
    "maxShowWidth": 3240,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },

  {
    "resourceId": "1831546686027661313",
    "relativeId": "1831546620760096769",
    "relativeType": "4",
    "content": "image/2024090512153270a13c6b917141ef.jpg",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/2024090512155247f7b1a709ee42de.jpg",
    "type": 1,
    "title": "",
    "description": "",
    "createTime": "2024-09-05 12:15:33",
    "maxShowHeight": 900,
    "maxShowWidth": 1600,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1831546685901832193",
    "relativeId": "1831546620760096769",
    "relativeType": "4",
    "content": "image/202409051215324f2b6a11f367438c.jpg",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20240905121604e9fce6121ce74493.jpg",
    "type": 1,
    "title": "",
    "description": "",
    "createTime": "2024-09-05 12:15:33",
    "maxShowHeight": 900,
    "maxShowWidth": 1600,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1831535661970685953",
    "relativeId": "1831535510417899521",
    "relativeType": "4",
    "content": "image/20240905113144b8f43d3f85df4d9a.jpg",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20240905113517ff678e4df4ac4322.jpg",
    "type": 1,
    "title": "东莞以城市之名，致敬改革开放和平凡建设者。",
    "description": "",
    "createTime": "2024-09-05 11:31:45",
    "maxShowHeight": 7087,
    "maxShowWidth": 12598,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1831535658556522497",
    "relativeId": "1831535510417899521",
    "relativeType": "4",
    "content": "image/202409051131437b4be9c8cd834fb1.jpg",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20240905113729f7bebf9a7df14bd9.jpg",
    "type": 1,
    "title": "天南海北的你， 进“莞”来，书写下一个传奇。",
    "description": "",
    "createTime": "2024-09-05 11:31:44",
    "maxShowHeight": 7087,
    "maxShowWidth": 12598,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1831535657122070529",
    "relativeId": "1831535510417899521",
    "relativeType": "4",
    "content": "image/20240905113143467d6d1d4d224b9c.jpg",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/202409051137079490f33e51a545c2.jpg",
    "type": 1,
    "title": "东莞不会辜负每一个认真生活、努力拼搏的人！",
    "description": "",
    "createTime": "2024-09-05 11:31:44",
    "maxShowHeight": 7087,
    "maxShowWidth": 12598,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  },
  {
    "resourceId": "1831535648314032129",
    "relativeId": "1831535510417899521",
    "relativeType": "4",
    "content": "image/20240905113141b1d4db774bd64329.jpg",
    "coverUrl": "https://publicadv-oss.timedg.com/cover/20240905113744ba41c43e154040ab.jpg",
    "type": 1,
    "title": "从“东莞东”出发，奔赴星辰大海。",
    "description": "",
    "createTime": "2024-09-05 11:31:42",
    "maxShowHeight": 7087,
    "maxShowWidth": 12598,
    "isAllowDownload": 1,
    "isShowIndex": null,
    "isTop": null,
    "sort": null,
    "sloganCategoryName": "",
    "type_dictText": "图片",
    "isAllowDownload_dictText": "是"
  }
]

class UI {
  // 后端数据
  backendData
  // 列表数据（二维数组）
  listData
  // 列表宽度
  listWidth
  // 列表项间隔
  itemGap
  // 每行最小高度
  minRowHeight
  // 每行最大图片数量
  maxRowLength
  // 容器元素
  containerElement

  constructor({ backendData, listWidth, itemGap, minRowHeight = 200, maxRowLength = 5, containerElement }) {
    if (!backendData) {
      throw new Error('缺失参数: backendData');
    } else if (!Array.isArray(backendData)) {
      throw new Error('参数类型错误: backendData 必须为数组');
    }
    if (!listWidth) {
      throw new Error('缺失参数: listWidth');
    } else if (typeof listWidth !== 'number') {
      throw new Error('参数类型错误: listWidth 必须为数字');
    }
    if (!itemGap) {
      throw new Error('缺失参数: itemGap');
    } else if (typeof itemGap !== 'number') {
      throw new Error('参数类型错误: itemGap 必须为数字');
    }
    if (minRowHeight < 1) {
      throw new Error('参数错误: minRowHeight 必须大于等于1');
    }

    this.backendData = backendData;
    this.listWidth = listWidth;
    this.itemGap = itemGap;
    this.minRowHeight = minRowHeight;
    this.maxRowLength = maxRowLength;
    this.containerElement = containerElement;
    this.listData = this.waterfallTransformData();
  }

  // 横向瀑布流布局算法
  waterfallTransformData() {
    // 预处理数据，计算宽高比
    const processedData = this.backendData.map(item => ({
      ...item,
      aspectRatio: item.maxShowWidth / item.maxShowHeight
    }));

    const rows = [];
    let i = 0;

    while (i < processedData.length) {
      // 从当前图片开始，尝试构建一行
      let rowItems = [];
      let j = i;

      // 先用最小行高估算能放多少张图片
      let estimatedWidth = 0;
      while (j < processedData.length && rowItems.length < this.maxRowLength) {
        const item = processedData[j];
        const itemWidth = this.minRowHeight * item.aspectRatio;

        // 计算加上当前图片后的总宽度（包括间隙）
        const newTotalWidth = estimatedWidth + (rowItems.length > 0 ? this.itemGap : 0) + itemWidth;

        // 如果加上这张图片后不超过容器宽度，或者这是第一张图片，则添加
        if (newTotalWidth <= this.listWidth || rowItems.length === 0) {
          rowItems.push(item);
          estimatedWidth = newTotalWidth;
          j++;
        } else {
          // 否则停止添加图片
          break;
        }
      }

      // 至少要有一张图片
      if (rowItems.length === 0 && i < processedData.length) {
        rowItems.push(processedData[i]);
        j = i + 1;
      }

      rows.push({
        items: rowItems,
        startIndex: i,
        endIndex: j
      });

      i = j;
    }

    // 处理每行的行高
    const result = [];
    for (let i = 0; i < rows.length; i++) {
      const row = rows[i];
      const isLastRow = (i === rows.length - 1);

      // 计算这行的最佳行高
      const rowHeight = this.calculateRowHeight(row.items, isLastRow);

      // 处理行内每个元素
      const processedRowItems = row.items.map(item => {
        // 计算显示尺寸
        const showWidth = Math.floor(rowHeight * item.aspectRatio);
        const showHeight = rowHeight;

        return {
          ...item,
          showWidth,
          showHeight,
          rect: {
            width: showWidth,
            height: showHeight
          }
        };
      });

      result.push(processedRowItems);
    }

    return result;
  }

  // 计算一行的行高
  calculateRowHeight(rowItems, isLastRow) {
    if (rowItems.length === 0) return 0;

    // 特殊处理：如果只有一个元素
    if (rowItems.length === 1) {
      const item = rowItems[0];

      // 如果不是最后一行，则强制拉伸至容器宽度，并调整行高以满足宽高比
      if (!isLastRow) {
        // 使用容器宽度作为图片宽度，根据宽高比计算高度
        const height = Math.floor(this.listWidth / item.aspectRatio);
        return height;
      }

      // 如果是最后一行，则优先使用最小行高
      const widthWithMinHeight = Math.floor(this.minRowHeight * item.aspectRatio);

      // 如果宽度超过容器宽度，则调整行高使宽度等于容器宽度
      if (widthWithMinHeight > this.listWidth) {
        return Math.floor(this.listWidth / item.aspectRatio);
      } else {
        // 否则使用最小行高
        return this.minRowHeight;
      }
    }

    // 对于多个元素的情况，使用二分查找计算最佳行高
    // 使得总宽度正好等于容器宽度
    let minRowHeight = this.minRowHeight;
    let maxRowHeight = 1000;
    let optimalRowHeight = minRowHeight;
    const tolerance = 1; // 容忍的误差范围
    const maxIterations = 20;

    for (let i = 0; i < maxIterations; i++) {
      const midRowHeight = (minRowHeight + maxRowHeight) / 2;
      let totalWidth = 0;

      for (let j = 0; j < rowItems.length; j++) {
        const itemWidth = Math.floor(midRowHeight * rowItems[j].aspectRatio);
        totalWidth += (j > 0 ? this.itemGap : 0) + itemWidth;
      }

      if (Math.abs(totalWidth - this.listWidth) <= tolerance) {
        optimalRowHeight = midRowHeight;
        break;
      } else if (totalWidth < this.listWidth) {
        minRowHeight = midRowHeight;
        optimalRowHeight = midRowHeight;
      } else {
        maxRowHeight = midRowHeight;
      }
    }

    return Math.max(this.minRowHeight, Math.floor(optimalRowHeight));
  }

  // 重新布局方法
  resizeLayout(newListWidth) {
    // 更新列表宽度
    this.listWidth = newListWidth;
    // 重新计算布局数据
    this.listData = this.waterfallTransformData();
    // 重新渲染
    this.theSecondWayRender();
  }

  theSecondWayRender() {
    const $container = $(this.containerElement);
    $container.empty(); // 清空容器

    // 使用双重循环渲染二维数组
    this.listData.forEach((row, rowIndex) => {
      const $row = $('<div>').addClass('waterfall-row');

      row.forEach((item, itemIndex) => {
        const $resourceItem = $('<div>')
          .addClass('resource-item')
          .attr('id', item.resourceId)
          .css({
            width: `${item.showWidth}px`,
            height: `${item.showHeight}px`,
            display: 'inline-block',
            marginRight: itemIndex < row.length - 1 ? `${this.itemGap}px` : '0'
          });

        const $img = $('<img>')
          .attr('src', item.coverUrl)
          .css({
            width: '100%',
            height: '100%',
            objectFit: 'cover'
          });

        const $title = $('<div>').addClass('title').text(item.title);

        $resourceItem.append($img);
        $resourceItem.append($title);
        $row.append($resourceItem);
      });

      $container.append($row);
    });
  }
}

let uiInstance = null;

function initializeWaterfall() {
  const $container = $('#waterfall-container');
  const containerElement = $container.get(0);
  const containerWidth = $container.width();

  if (containerElement && containerWidth > 0) {
    // 创建或更新UI实例
    if (uiInstance) {
      uiInstance.resizeLayout(containerWidth);
    } else {
      uiInstance = new UI({
        backendData: mockData,
        listWidth: containerWidth,
        itemGap: 10,
        minRowHeight: 200,
        maxRowLength: 5,
        containerElement: containerElement
      });
      // 确保正确设置宽度并重新计算数据后再渲染
      uiInstance.resizeLayout(containerWidth);
    }
    return true;
  }
  return false;
}

$(document).ready(function () {
  setTimeout(function () {
    initializeWaterfall();
  }, 100);

  // 监听窗口大小变化
  let resizeTimer;
  $(window).on('resize', function () {
    // 防抖处理，避免频繁触发
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(function () {
      const $container = $('#waterfall-container');
      const newWidth = $container.width();
      if (uiInstance && newWidth > 0) {
        uiInstance.resizeLayout(newWidth);
      }
    }, 500);
  });
});
